<template>
  <div class="attachment-input">
    <el-upload
      ref="upload"
      :action="uploadAction"
      :multiple="multiple"
      :limit="limit"
      :file-list="fileList"
      :before-upload="beforeUpload"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-remove="handleRemove"
      :on-exceed="handleExceed"
      :accept="acceptTypes"
      :disabled="param.disabled"
      list-type="text"
    >
      <el-button size="mini" :disabled="param.disabled">
        <i class="el-icon-upload"></i>
        选择文件
      </el-button>
      <div v-if="param.placeholder" slot="tip" class="el-upload__tip">
        {{ param.placeholder }}
      </div>
    </el-upload>
    
    <!-- 预览模态框 -->
    <el-dialog
      :visible.sync="previewVisible"
      :title="previewTitle"
      width="60%"
      top="5vh"
    >
      <div v-if="previewUrl" class="preview-content">
        <img v-if="isImage(previewUrl)" :src="previewUrl" class="preview-image" />
        <div v-else class="preview-file">
          <i class="el-icon-document" style="font-size: 48px; color: #409eff;"></i>
          <p>该文件类型不支持预览</p>
          <el-button type="primary" @click="downloadFile(previewUrl)">
            下载文件
          </el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'AttachmentInput',
  props: {
    param: {
      type: Object,
      required: true
    },
    value: {
      type: [String, Array],
      default: ''
    }
  },
  data() {
    return {
      fileList: [],
      previewVisible: false,
      previewUrl: '',
      previewTitle: ''
    }
  },
  computed: {
    // 上传地址（实际项目中替换为真实API地址）
    uploadAction() {
      return this.param.uploadUrl || '/api/upload'
    },
    
    // 是否支持多文件
    multiple() {
      return this.param.multiple !== false
    },
    
    // 文件数量限制
    limit() {
      return this.param.maxFiles || 10
    },
    
    // 接受的文件类型
    acceptTypes() {
      return this.param.accept || '*/*'
    }
  },
  watch: {
    value: {
      handler(newVal) {
        this.updateFileList(newVal)
      },
      immediate: true
    }
  },
  methods: {
    // 更新文件列表
    updateFileList(value) {
      if (!value) {
        this.fileList = []
        return
      }
      
      if (Array.isArray(value)) {
        this.fileList = value.map((file, index) => ({
          name: file.name || `文件${index + 1}`,
          url: file.url || file
        }))
      } else {
        this.fileList = [{
          name: '附件',
          url: value
        }]
      }
    },
    
    // 上传前验证
    beforeUpload(file) {
      const isValid = this.validateFile(file)
      
      if (!isValid) {
        this.$message.error('文件格式或大小不符合要求')
        return false
      }
      
      return true
    },
    
    // 验证文件
    validateFile(file) {
      // 文件类型验证
      if (this.param.accept && this.param.accept !== '*/*') {
        const acceptTypes = this.param.accept.split(',').map(type => type.trim())
        const fileExtension = '.' + file.name.split('.').pop().toLowerCase()
        const isValidType = acceptTypes.some(type => {
          if (type.startsWith('.')) {
            return fileExtension === type.toLowerCase()
          }
          return file.type.match(type.replace('*', '.*'))
        })
        
        if (!isValidType) {
          return false
        }
      }
      
      // 文件大小验证（默认10MB）
      const maxSize = this.param.maxSize || 10 * 1024 * 1024
      if (file.size > maxSize) {
        return false
      }
      
      return true
    },
    
    // 上传成功
    handleSuccess(response, file) {
      const fileUrl = response.data?.url || response.url || file.url
      
      if (this.multiple) {
        const currentValue = Array.isArray(this.value) ? [...this.value] : []
        currentValue.push(fileUrl)
        this.emitChange(currentValue)
      } else {
        this.emitChange(fileUrl)
      }
      
      this.$message.success('文件上传成功')
    },
    
    // 上传失败
    handleError(error, file) {
      console.error('文件上传失败:', error,file)
      this.$message.error('文件上传失败')
    },
    
    // 文件移除
    handleRemove(file, fileList) {
        console.error('文件移除:',file)
      if (this.multiple) {
        const urls = fileList.map(item => item.url)
        this.emitChange(urls)
      } else {
        this.emitChange('')
      }
    },
    
    // 文件超出限制
    handleExceed(files, fileList) {
      console.error('文件超出限制:',files,fileList)
      this.$message.warning(`最多只能上传${this.limit}个文件`)
    },
    
    // 判断是否为图片
    isImage(url) {
      const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']
      return imageExtensions.some(ext => url.toLowerCase().includes(ext))
    },
    
    // 预览文件
    previewFile(file) {
      this.previewUrl = file.url
      this.previewTitle = file.name
      this.previewVisible = true
    },
    
    // 下载文件
    downloadFile(url) {
      const link = document.createElement('a')
      link.href = url
      link.download = url.split('/').pop()
      link.click()
    },
    
    // 触发变化事件
    emitChange(value) {
      const isValid = this.validateAttachments(value)
      const message = isValid ? '' : '附件不符合要求'
      
      this.$emit('change', {
        value,
        isValid,
        message
      })
    },
    
    // 验证附件
    validateAttachments(value) {
      if (!value) {
        return !this.param.required
      }
      
      if (Array.isArray(value)) {
        if (this.param.required && value.length === 0) {
          return false
        }
        
        if (this.param.maxFiles && value.length > this.param.maxFiles) {
          return false
        }
      } else {
        if (this.param.required && !value) {
          return false
        }
      }
      
      return true
    }
  }
}
</script>

<style scoped>
.attachment-input {
  width: 100%;
}

.preview-content {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 400px;
}

.preview-image {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
}

.preview-file {
  text-align: center;
  padding: 40px;
}

:deep(.el-upload-list__item) {
  transition: none !important;
}
</style>